<?php

namespace IYUU\sdk\CoolQ;

use BadRequestException;
use InternalServerErrorException;

/**
 * 事件工厂(事件路由器)，根据消息的事件类型，创建对象
 * - 创建 IYUU\sdk\CoolQ\Event 命名空间下的对象
 * Class Factory
 * @package IYUU\sdk\CoolQ
 */
class Factory
{
    /**
     * @param Request $request
     * @return Event
     * @throws BadRequestException
     * @throws InternalServerErrorException
     */
    public static function generateService(Request $request): Event
    {
        $class = $request->getServiceClass();
        $action = $request->getServiceAction();

        if (empty($class) || empty($action)) {
            throw new BadRequestException("非法服务");
        }

        // 事件处理类名字（包含命名空间）
        $eventClassName = "\\IYUU\\sdk\\CoolQ\\Event\\" . ucfirst($class);
        if (!class_exists($eventClassName)) {
            throw new BadRequestException("服务类不存在{$eventClassName}", 1);
        }

        // 实例化
        $class = new $eventClassName($request);
        if (!is_subclass_of($class, Event::class)) {
            throw new InternalServerErrorException("{$eventClassName} 没有继承父类 " . Event::class);
        }

        if (!method_exists($class, $action) || !is_callable(array($class, $action))) {
            throw new BadRequestException("服务类方法不可调用 {$eventClassName}");
        }

        // 调用事件类的初始化方法
        if (method_exists($class, 'init') && is_callable(array($class, 'init'))) {
            $class->init();
        }

        return $class;
    }
}
